<?php

# langito project
# mysql class

# class constants
define('dbquery_host', $conf['host']);
define('dbquery_user', $conf['user']);
define('dbquery_pass', $conf['pass']);
define('dbquery_database', $conf['database']);

define('dbquery_character_set', $conf['mysql_character_set']);
define('dbquery_display_errors', $conf['mysql_display_errors']);
define('dbquery_cache', $conf['mysql_cache']);
define('dbquery_cache_modifier', '');
define('dbquery_debug', false);

class dbconnect {
	var $connection;
	var $dbname;

	function dbconnect() {
		$this->connection = @mysql_connect(dbquery_host,dbquery_user,dbquery_pass) or die("<b>Could not connect to MySQL server:</b><br />Check your MySQL preferences in includes/conf.php!");
		$this->dbname = dbquery_database;
		$mysql_select_db = mysql_select_db($this->dbname) or die("<b>MySQL server error:</b>:<br />".mysql_error($this->connection)."<br />Check your MySQL preferences in includes/conf.php!");
		mysql_query('SET CHARACTER SET '.dbquery_character_set);
	}

	function &init() {
		static $instance;

		if(!isset($instance)) {
			$instance = new dbconnect;
		}

		return $instance;
	}
}

class dbquery {
	var $result;
	var $dbase;
	
	#fields to be cleared after running SQL statement (not stored in cache)
	var $clear_fields;

	#cache variables
	var $cache_state;
	var $cache_file;
	var $cache_buffer;
	var $cache_cache_buffer_index;

	#some default variables
	var $strip_union; #give error when running UNION MySQL directive
	var $cache_dir; #default sql cache directory

	static $query_count=0;

	# automatyczne polaczenie z baza
	function dbquery() {
		$this->dbase = dbconnect::init();

		$this->cache_state=0;
		$this->cache_file;
		$this->cache_buffer;
		$this->cache_buffer_index=-1;
		$this->cache_buffer_length=0;

		$this->clear_fields=array();
		$this->strip_union=true; 
		$this->cache_dir='cache/sql/';
	}
	
	#ustawianie pol tabel ktore chcemy ustawic na NULL
	function clear_fields($clear_fields=array()) {
		$this->clear_fields=$clear_fields;
	}
	
	#cache zapytan SQL
	function cache($handle = '', $dir=''){

		#make defaults
		$this->cache_state=0;
		$this->cache_file=NULL;
		$this->cache_buffer=NULL;
		$this->cache_buffer_index=-1;
		
		$dir=$dir.'/';
		if($handle && dbquery_cache){
			$handle = dbquery_cache_modifier.$handle;

			if(file_exists($this->cache_dir.$dir.$handle.'.php')){
				$this->cache_state = 1;
				$this->cache_buffer = unserialize($this->file_get_contents($this->cache_dir.$dir.$handle.'.php'));
				$this->cache_buffer_length = count($this->cache_buffer);
			} else {
				$this->cache_state = 2;
				$this->cache_file = $this->cache_dir.$dir.$handle.'.php';
			}
		}
		else
			$this->cache_state = 0;
	}

	function cache_write(&$what) {
		$fp = fopen($this->cache_file, 'w');
		fwrite($fp, '<?php exit; /*'.serialize($what).'*/?>');
		fclose($fp);
	}

	#clear sql cache $handle - name, $dir - directory, $time
	function clear_cache($handle, $dir='', $time=false){
		$dir=$dir.'/';

		$handle='*_'.$handle;

		$start=microtime(1);

		if(dbquery_cache){
			#if handle is set we search all files having handle in name
			if($handle) {
				$f=glob_($this->cache_dir.$dir.$handle);
				if($f){
					foreach ($f as $file) {
						@unlink($file);
						
						if($time) {
							if(microtime(1)-$start>ini_get('max_execution_time')-2){
								redirect('index.php?function=delete_cache&what=sql');
								exit;
							}
						}
					}
				}
			}
			#else we remove 
			else {
				if ($hndl = opendir($this->cache_dir.$dir)) {
					while (false !== ($file = readdir($hndl))) {
						if ($file != "." && $file != "..") {
							@unlink($this->cache_dir.$dir.$file);
							
							if($time) {
								if(microtime(1)-$GLOBALS['time_start']>ini_get('max_execution_time')-3){
									redirect('index.php?function=delete_cache&what=sql');
									exit;
								}
							}
						}
					}
					closedir($hndl);
				}
			}
		}
	}

	# cheking if cache exists
	function cache_check($handle, $dir){
		if(file_exists($dir.'/'.$handle))
			return true;
		else
			return false;
	}

	# run query
	function query($query) {
		$_SESSION['last_query']=$query;
		
		#if we don't cache
		if($this->cache_state != 1){
			if($this->strip_union && strpos(strtolower($query), "union")!==false) {
				$q=preg_replace("#'[^\n]*?'#", '', $query);
				$q=preg_replace('#"[^\n]*?"#', '', $q);
				$q=preg_replace('#`[^\n]*?`#', '', $q);
				if(strpos(strtolower($q), "union")!==false) exit("You are using UNION SQL statement in your query, which is disabled by default for security reasons.<br />If it is necessary disable it includes/classes/mysql.class.db.php, or report SQL Injection hole you've just found on our webpage!");
			}
			
			if(dbquery_debug)
				echo($query."<br />");
			
			dbquery::$query_count++;
			$this->result = mysql_query($query);

			return $this->result;
		}	

		return 1;
	}

	# zwraca mysql_fetch_array
	function fetch_array($res_type=MYSQL_BOTH) {
		if($this->cache_state == 1) {
			$this->cache_buffer_index++;

			#turn off cache
			if($this->cache_buffer_index == $this->cache_buffer_length) {
				$this->cache_state=0;
				$this->cache_file=NULL;
				$this->cache_buffer=NULL;
				$this->cache_buffer_index=-1;
				$this->cache_buffer_length=0;
				return false;
			}

			return $this->cache_buffer[$this->cache_buffer_index];
		}
		else {
			if($row = mysql_fetch_array($this->result, $res_type)){
				#usuwanie pol z $this->clear_fields z wyników
				foreach($this->clear_fields as $k => $v) unset($row[$v]);

				if($this->cache_state == 2){
					$this->cache_buffer[] = $row;
				}
				if($save && dbquery_cache)
					$this->cache_write($this->cache_buffer);

				return $row;
			} else {
				if($this->cache_state != 1) mysql_free_result($this->result);
				if($this->cache_state == 2)
					$this->cache_write($this->cache_buffer);

				#turn off cache
				$this->cache_state=0;
				$this->cache_file=NULL;
				$this->cache_buffer=NULL;
				$this->cache_buffer_index=-1;
				$this->cache_buffer_length=0;
		
				return false;
			}
		}
		return false;
	}

	# zwraca mysql_fetch_object
	function fetch_object($save=false) {
		if($this->cache_state == 1){
			$this->cache_buffer_index++;

			#turn off cache
			if($this->cache_buffer_index == $this->cache_buffer_length) {
				$this->cache_state=0;
				$this->cache_file=NULL;
				$this->cache_buffer=NULL;
				$this->cache_buffer_index=-1;
				$this->cache_buffer_length=0;
				return false;
			}	

			return $this->cache_buffer[$this->cache_buffer_index];
		}
		else{
			if($row = mysql_fetch_object($this->result)){
				#usuwanie pol z $this->clear_fields z wyników
				foreach($this->clear_fields as $k => $v) unset($row->$v);

				if($this->cache_state == 2){
					$this->cache_buffer[] = $row;
				}
				if($save && dbquery_cache)
					$this->cache_write($this->cache_buffer);

				return $row;
			}
			else {
				if($this->cache_state != 1) mysql_free_result($this->result);
				if($this->cache_state == 2)
					$this->cache_write($this->cache_buffer);

				#turn off cache
				$this->cache_state=0;
				$this->cache_file=NULL;
				$this->cache_buffer=NULL;
				$this->cache_buffer_index=-1;
				$this->cache_buffer_length=0;
		
				return false;
			}
		}
		return false;
	}

	# zwraca wyniki jako tablice asocjacyjna
	function fetch_assoc() {
		return @mysql_fetch_assoc($this->result);
	}

	# zwaraca mysql_num_rows
	function num_rows($save=false, $get=false) {
		if($this->cache_state == 1 && !$get){
			return $this->cache_buffer;
		}
		elseif($this->cache_state == 1 && $get){
			return count($this->cache_buffer);
		}
		else{
			$row = @mysql_num_rows($this->result);
			if($this->cache_state == 2 && $save)
				$this->cache_write($row);
			
			return $row;
		}
	}

	# returns mysql_list_fields
	function list_fields($table) {
		return mysql_list_fields($this->dbase->dbname, $table, $this->dbase->connection);
	}

	# returns mysql_field_name
	function field_name($fields, $i) {
		return mysql_field_name($fields, $i);
	}

	# returns mysql_num_fields
	function num_fields($fields=NULL) {
		if(!$fields) $fields=$this->result;
		return mysql_num_fields($fields);
	}

	# returns mysql_fetch_field
	function fetch_field($i=NULL) {
		return mysql_fetch_field($this->result, $i);
	}

	# returns ostatnie dodane id
	function insert_id() {
		return mysql_insert_id($this->dbase->connection);
	}
	
	# returns runned queries count
	function query_count() {
		return dbquery::$query_count;
	}

	# display error if dbquery_display_errors is set, third parameter 
	function err($file=NULL, $line=NULL, $bool=false) {
		if(dbquery_display_errors or $bool)
			die("Query: $_SESSION[last_query]<br />File: $file, linie: $line;<br />Error: ".mysql_error());
	}
	
	# get MySQL server version
	function version() {
		return substr(mysql_get_server_info(), 0, 1);
	}
	
	# returns DEAFAULT CHARSET=dbquery_character_set if this tag is needed during database creation
	function default_charset() {
		if($this->version()>=5)
		   return "DEFAULT CHARSET=".dbquery_character_set;
		else return "";
	}

	# get file contents with ommiting php code, added to hide file content
	function file_get_contents($file) {
		$buffer_length=2048;
		
		$fp=@fopen($file, 'r');
		fseek($fp, 0, SEEK_END);

		$end=ftell($fp)-14-4;
		$times=(INT)($end/$buffer_length);
		fseek($fp, 14);

		$data='';
		for($i=0;$i<$times;$i++) { $data.=fread($fp, $buffer_length); $end-=$buffer_length; }
		
		if($end>0)
			$data.=fread($fp, $end);

		@fclose($fp);
		return $data;
	}
}

?>
